﻿using System.Data.Entity;

using NLog;

using Sc.Domain.Entities;

namespace SC.Infrastructure.Persistence
{
	public class Context : DbContext
	{
		private readonly Logger _logger = LogManager.GetCurrentClassLogger();

		public Context()
			: base("ScDb")
		{
			_logger.Info("Creating Context");
		}

		#region Repositories

		public IDbSet<Employee> Employees { get; set; }
		public IDbSet<JobTitle> JobTitles { get; set; }
		public IDbSet<Shift> Shifts { get; set; }
		public IDbSet<ShiftRequest> ShiftRequests { get; set; }
		public IDbSet<ShiftRequirements> ShiftRequirements { get; set; }

		#endregion

		protected override void OnModelCreating(DbModelBuilder modelBuilder)
		{
			_logger.Info("Creating model");

			JobTitlesMappingConfiguration(modelBuilder);
			EmployeesMappingConfiguration(modelBuilder);
			ShiftRequirementsMappingConfiguration(modelBuilder);
			ShiftsMappingConfiguration(modelBuilder);
			ShiftRequestsMappingConfiguration(modelBuilder);

			base.OnModelCreating(modelBuilder);

			_logger.Info("Model created");
		}

		#region Mapping Configurations

		private static void EmployeesMappingConfiguration(DbModelBuilder modelBuilder)
		{
			modelBuilder.Entity<Employee>().ToTable("Employees");

			modelBuilder.Entity<Employee>().HasKey(e => e.Id);
			modelBuilder.Entity<Employee>().Property(e => e.Id).HasColumnName("Employee_ID");

			modelBuilder.Entity<Employee>().Property(e => e.FirstName).IsRequired();
			modelBuilder.Entity<Employee>().Property(e => e.LastName).IsRequired();

			modelBuilder.Entity<Employee>().HasMany(e => e.JobTitles).WithMany();
		}

		private static void ShiftsMappingConfiguration(DbModelBuilder modelBuilder)
		{
			modelBuilder.Entity<Shift>().ToTable("Shifts");

			modelBuilder.Entity<Shift>().HasKey(s => s.Id);
			modelBuilder.Entity<Shift>().Property(s => s.Id).HasColumnName("Shift_ID");

			modelBuilder.Entity<Shift>().Property(s => s.Name).IsRequired();
			modelBuilder.Entity<Shift>().Property(s => s.Name).HasMaxLength(20);

			modelBuilder.Entity<Shift>().Property(s => s.StartDate).IsRequired();
			modelBuilder.Entity<Shift>().Property(s => s.EndDate).IsRequired();

			modelBuilder.Entity<Shift>().HasMany(s => s.ShiftRequirements).WithMany();
		}

		private static void ShiftRequestsMappingConfiguration(DbModelBuilder modelBuilder)
		{
			modelBuilder.Entity<ShiftRequest>().ToTable("ShiftRequests");

			modelBuilder.Entity<ShiftRequest>().HasKey(s => s.Id);
			modelBuilder.Entity<ShiftRequest>().Property(s => s.Id).HasColumnName("ShiftRequest_ID");

			modelBuilder.Entity<ShiftRequest>().HasRequired(sr => sr.Employee).WithMany().HasForeignKey(sr => sr.EmployeeId);

			modelBuilder.Entity<ShiftRequest>().HasMany(sr => sr.Shifts).WithMany();
		}

		private static void ShiftRequirementsMappingConfiguration(DbModelBuilder modelBuilder)
		{
			modelBuilder.Entity<ShiftRequirements>().ToTable("ShiftRequirements");

			modelBuilder.Entity<ShiftRequirements>().HasKey(sr => sr.Id);
			modelBuilder.Entity<ShiftRequirements>().Property(sr => sr.Id).HasColumnName("ShiftRequirements_ID");

			modelBuilder.Entity<ShiftRequirements>().HasRequired(sr => sr.JobTitle).WithMany().HasForeignKey(sr => sr.JobTitleId);

			modelBuilder.Entity<ShiftRequirements>().HasMany(sr => sr.Employees).WithMany();
		}

		private static void JobTitlesMappingConfiguration(DbModelBuilder modelBuilder)
		{
			modelBuilder.Entity<JobTitle>().ToTable("JobTitles");

			modelBuilder.Entity<JobTitle>().HasKey(jt => jt.Id);
			modelBuilder.Entity<JobTitle>().Property(jt => jt.Id).HasColumnName("JobTitle_ID");

			modelBuilder.Entity<JobTitle>().Property(jt => jt.Name).IsRequired();
			modelBuilder.Entity<JobTitle>().Property(jt => jt.Name).HasMaxLength(20);
		}

		#endregion
	}
}